package com.multimedia.scala.sudoku

object Checker {

	def scanRow(data: List[List[Int]], row: Int, res: scala.collection.mutable.Set[Int]) {
		data(row).foreach(res.remove(_))
	}
	
	def scanCol(data: List[List[Int]], col: Int, res: scala.collection.mutable.Set[Int]) {
		data.foreach(s1 => res.remove(s1(col)))
	}

	def scanBlock(data: List[List[Int]], row: Int, col: Int, res: scala.collection.mutable.Set[Int]) {
	    val coord = getBlockCoordinates(row, col)
	    for (i <- coord._1 to coord._1+2)
	      for (j <- coord._2 to coord._2+2)
	        res.remove(data(i)(j))
	}

	/** returns left top coordinate of a block */
	private def getBlockCoordinates(row: Int, col: Int): (Int, Int) = {
		return (row - row%3, col - col%3)
	}

	    private def checkRows(data: List[List[Int]]): Boolean = {
	         for (i <- 0 to 8) {
	        	 var res = scala.collection.mutable.Set(1, 2, 3, 4, 5, 6, 7, 8, 9)
	        	 scanRow(data, i, res)
	        	 if (!res.isEmpty){
	        	     return false
	        	 }
	         }
	         return true
	    }
	    private def checkCols(data: List[List[Int]]): Boolean = {
	         for (i <- 0 to 8) {
	        	 var res = scala.collection.mutable.Set(1, 2, 3, 4, 5, 6, 7, 8, 9)
	        	 scanCol(data, i, res)
	        	 if (!res.isEmpty){
	        	     return false
	        	 }
	         }
	         return true
	    }
	    private def checkBlocks(data: List[List[Int]]): Boolean = {
	         for (i <- 0 to 2)
		         for (j <- 0 to 2) {
		        	 var res = scala.collection.mutable.Set(1, 2, 3, 4, 5, 6, 7, 8, 9)
		        	 scanBlock(data, i*3, j*3, res)
		        	 if (!res.isEmpty){
		        	     return false
		        	 }
		         }
	         return true
	    }
	    def checkField (data: List[List[Int]]): Boolean = {
	         return checkRows(data)&&checkCols(data)&&checkBlocks(data)
	    }
}